#pragma once

#include "vector.h"

namespace g2 {

template <typename T>
class basic_translation;

typedef basic_translation<double> translation;
typedef basic_translation<float> translationf;
typedef basic_translation<long double> translationl;

// Translation transform
template <class T>
class basic_translation
{
public:
	typedef T element_type;
public:
	basic_vector<T> d; ///< p_new = p_old + d
public:
	basic_translation() 
		{ }
	basic_translation(basic_vector<T> const & displacement) : d(displacement)
		{ }
	basic_translation & identity() 
		{ d.zero(); return * this; }

	friend bool operator == (const basic_translation<T> & lhs, const basic_translation<T> & rhs) 
		{ return lhs.d == rhs.d; }
	friend bool operator != (const basic_translation<T> & lhs, const basic_translation<T> & rhs) 
		{ return !(lhs == rhs); }

	basic_vector<T> operator ()(basic_vector<T> const & p_old) const 
		{ return p_old + d;	};

	basic_translation<T> inverse() const
		{ return basic_translation<T>(-d); }
	basic_vector<T> inverse(const basic_vector<T> & p_new) const
		{ return p_new - d; }

	friend basic_translation<T> operator * (
		const basic_translation<T> & a1, const basic_translation<T> & a0) 
	{ return basic_translation<T>(a1.d + a0.d);	}

  /// modifies the transformation so that it remains valid after scaling of all points in s times
  basic_translation & scale(T s)
    { d *= s; return * this; }

  static const char * name() { return "translation"; }
};

} //namespace g2
